package rmmk.framework.gui.knnParamSelection;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;

import rmmk.algorithms.features.FrequentNumbersGlobal;
import rmmk.algorithms.features.abstraction.AbstractFeatureExtractor;
import rmmk.algorithms.features.global.PairsOfWordsGlobal;
import rmmk.algorithms.preprocessing.OperationManager;
import rmmk.algorithms.preprocessing.WordExtractor;
import rmmk.algorithms.preprocessing.abstraction.IWordFilter;
import rmmk.algorithms.preprocessing.config.DistanceMetric;
import rmmk.algorithms.preprocessing.config.KnnType;
import rmmk.algorithms.preprocessing.filters.ToLowercaseNoInterpunctionFilter;
import rmmk.algorithms.similarityMeasures.abstraction.AbstractSimilarityMeasure;
import rmmk.datasources.parsing.ClassTypes;
import rmmk.datasources.parsing.DocumentReader;
import rmmk.framework.Analize;
import rmmk.framework.datasources.Document;
import rmmk.framework.datasources.DocumentSetSelector;

public class KnnParamsPanel extends JPanel implements ActionListener{
	
	private static final long serialVersionUID = 1L;
	private final static Logger logger = Logger.getLogger(""); 
	JComboBox<String> knnTypes;
	JComboBox<String> distanceMetrics;
	KSelection kSelection;
	DataProportionsPanel dataProportionPanel;
	JButton startButton;
	OperationManager om;
	
	public KnnParamsPanel(OperationManager om){
	super();
	
	this.om = om;
	kSelection = new KSelection();
	add(kSelection);
	
	setLayout(new GridLayout(5,2,0,5));
	knnTypes = new JComboBox<String>();
	((JLabel)knnTypes.getRenderer()).setHorizontalAlignment(JLabel.CENTER);
	knnTypes.addItem("Classify using feature vector");
	knnTypes.addItem("Classify using similarity measure");
	add(knnTypes);

	distanceMetrics = new JComboBox<String>();
	((JLabel)distanceMetrics.getRenderer()).setHorizontalAlignment(JLabel.CENTER);
	distanceMetrics.addItem("Euclides");
	distanceMetrics.addItem("Czybyszew");
	distanceMetrics.addItem("Manhattan");
	add(distanceMetrics);

	dataProportionPanel = new DataProportionsPanel();
	add(dataProportionPanel);
	
	startButton = new JButton("Start computing...");
	add(startButton);
	}
	
	public int getKParameter(){
		return Integer.parseInt(kSelection.getkSelectionInput());
	}

	public DistanceMetric getMetric(){
		
		String selectedMetric = (String) distanceMetrics.getSelectedItem();
		
		switch (selectedMetric) {
		case "Euclides":
			return DistanceMetric.Euclides;

		case "Czybyszew":
			return DistanceMetric.Czybyszew;

		case "Manhattan":
			return DistanceMetric.Manhattan;
	
		}
		return null;
	}
	
	public Double getTrainDataPercentage(){
		
		return dataProportionPanel.getDataProportionInput();
	}
	
	public KnnType getknnType(){
		
		String selectedMetric = (String) knnTypes.getSelectedItem();
			
		switch (selectedMetric) {
		case "Classify using feature vector":
			return KnnType.FeatureVector;

		case "Classify using similarity measure":
			return KnnType.SimilarityMeasure;
			
		}
		return null;
	}

	@Override
	public void actionPerformed(ActionEvent e) {

		Long start = System.nanoTime();

		om = new OperationManager();
		setOperationManagerParams();
		
		DocumentReader dr = new DocumentReader();

		List<Document> allDocuments = dr.readDefautDocuments();
		IWordFilter[] iwe = new IWordFilter[] { new ToLowercaseNoInterpunctionFilter() };
		WordExtractor.extractWords(allDocuments, Arrays.asList(iwe));
	
		DocumentSetSelector dss = new DocumentSetSelector(allDocuments);
		dss.setTrainToTestSetProportion(dataProportionPanel.getDataProportionInput());
		logger.info("Train to test data proportion: "+dss.getTrainToTestSetProportion());
		dss.addDesiredCategory(ClassTypes.PLACES);
		dss.setLimit(1);
		dss.addCategoryName("west-germany");
		dss.addCategoryName("usa");
		dss.addCategoryName("france");
		dss.addCategoryName("uk");
		dss.addCategoryName("canada");
		dss.addCategoryName("japan");
		
		List<Document> trainDocuments = dss.getTrainSet();

		PairsOfWordsGlobal pwg = new PairsOfWordsGlobal();
		pwg.calculate(trainDocuments);
		FrequentNumbersGlobal ng = new FrequentNumbersGlobal();
		ng.calculate(trainDocuments);

		om.teach(trainDocuments);
		
		List<Document> testDocuments = dss.getTestSet();
		logger.info("Classifying documents...");
		testDocuments = om.predict(testDocuments);
		
		Analize.analize(testDocuments);
		
		Long finished = System.nanoTime();
		logger.info("Time " + (finished - start) / 1000000000 + " seconds");
	}

	private void setOperationManagerParams() {
		om.getAkc().setType(getknnType());
		om.setDm(getMetric());
		/*om.getSimilarityMeasureManager().addMeasure(smPanel.getSimilarityMeasures());
		om.getFeatureManager().addFeature(fsPanel.getFeatures());*/
		om.setK(getKParameter());
		logger.info("\nParameters set");
		logger.info("\nK for kNN: "+om.getAkc().getK());
		logger.info("\nKnn type: "+om.getAkc().getType().name());
		if(om.getAkc().getType().equals(KnnType.FeatureVector)){
		logger.info("\nChosen distance metric: "+om.getDm().name());
		logger.info("\nChosen feature extractors:");
		for (AbstractFeatureExtractor fe : om.getFeatureManager().getFeatures()) {
			logger.info(fe.getClass().getSimpleName()+",");
		}
		}else{
			logger.info("\nChosen similarity measure:");
			for (AbstractSimilarityMeasure smm : om.getSimilarityMeasureManager().getSimilarityMeasures()) {
				logger.info(smm.getClass().getSimpleName());	
			}
		}		
		
	}
	
}